//
// Created by zhouheyu on 17-11-26.
//

#ifndef LRU_LRU_H
#define LRU_LRU_H
//和缓冲区相关的状态标识
#define CACHE_INVALID 0
#define CACHE_VALID 1
#define CACHE_INCLRU 2
#define CACHE_INDLRU 3
//定义cache的读写延时
#define CACHE_READ_DELAY 0.0005
#define CACHE_WRITE_DELAY 0.0005
//自己定义flash的读写延迟
#define FLASH_READ_DELAY 0.05
#define FLASH_WRITE_DELAY 0.25
//cache (read/write count) variable
int cache_read_num;
int cache_write_num;
//表示当前的CLRU和DLRU状态
int CACHE_CLRU_NUM_ENTRIES;
int CACHE_DLRU_NUM_ENTRIES;
int CACHE_NUM_ENTRIES;

//当前的cache的age最小的索引，也就是LPN，NandPage的下标
int cache_min_index;
int cache_max_index;

//定义算法需要用到的结构体
//page_entry表示所用数据页在缓冲区可能的状态
struct page_entry{
    int cache_status;
    int cache_age;//在缓冲区滞留的时间，越久age越大
    int cache_update;//缓冲区更新的标志
};
unsigned  int NandPage_Num;//只表示数据页
struct  page_entry *NandPage;

//关于cache的读写统计 在对应的fast.c中的lm_init初始化
int buffer_cnt;
int buffer_hit_cnt;
int buffer_miss_cnt;
int buffer_write_hit;
int buffer_write_miss;
int buffer_read_hit;
int buffer_read_miss;
int physical_write;
int physical_read;
//和算法相关的函数定义
//测试需要用的初始化函数
void InitVariable();//初始化统计变量,还有分配NandPage的内存
//打印输出最后统计的结果
void PrintResultStat();
//注意释放分配的内存
void FreeVariable();

void init_my_arr();//初始化自己算法中所需要用到的数组
void reset_cache_stat();
double calculate_delay_cache();
int my_find_cache_min(int *arr,int arrMaxSize);
int my_find_cache_max(int *arr,int arrMaxSize);
int search_table(int *arr,int size,int val);
int calculate_arr_positive_num(int *arr,int size);
int find_free_pos(int *arr,int size);
double CacheManage(unsigned int secno,int scount,int operation);

int FindLPNInCache(int LPN);
//命中后修改对应的NandPage的状态,无论命中还是初次加载数据页都需要调用更新NandPage状态
void UpdateNandPageStat(int LPN,int operation);
//重置对应的NandPage的状态为初始状态的值
void ResetNandPageStat(int LPN);
//选择lru_cache_arr中的剔除对象，返回的是lru_cache_arr即将提出的对象的索引
int FindVictimInLruCacheArr();
//剔除lru数组中的剔除对象并重置相应的NandPage，统计对应的物理回写次数
double DelVictimFromLRU(int Victim_page_index);
double AddNewToLRU(int LPN,int operation);
#endif //LRU_LRU_H
